package com.spn.blog.article.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spn.blog.article.dao.mapper.ArticleMapper;
import com.spn.blog.article.dao.mapper.CommentsMapper;
import com.spn.blog.common.dao.pojo.Article;
import com.spn.blog.common.dao.pojo.Comment;
import com.spn.blog.common.vo.CommentVo;
import com.spn.blog.common.vo.Result;
import com.spn.blog.common.vo.UserVo;
import com.spn.blog.common.vo.params.CommentParam;
import com.spn.blog.service.article.CommentsService;
import com.spn.blog.service.login.SysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@DubboService
@Service
public class CommentsServiceImpl extends ServiceImpl<CommentsMapper, Comment> implements CommentsService {

    @Autowired
    private CommentsMapper commentsMapper;
    @Autowired
    private ThreadService threadService;
    @Autowired
    private ArticleMapper articleMapper;
    @DubboReference
    private SysUserService sysUserService;

    @Override
    public Result comentsByArticleId(Long id) {
        /**
         * 1. 根据文章id查询所有评论，从comment表查询
         * 2. 根据作者的id查询作者信息
         * 3. 判断 如果level=1，要去查询它有没有子评论(level=1表示它是一级评论，就要看是否有二级评论)
         * 4. 如果有 根据评论id进行查询（parent_id）
         */

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getArticleId, id);
        queryWrapper.eq(Comment::getLevel, 1);
        List<Comment> comments = commentsMapper.selectList(queryWrapper);
        //进行comments赋值给CommentVo，以及其他字段赋值给CommentVo
        List<CommentVo> commentVoList = copyList(comments);
        return Result.success(commentVoList);
    }

    private List<CommentVo> copyList(List<Comment> comments) {
        List<CommentVo> commentVoList = new ArrayList<>();
        for (Comment comment : comments) {
            commentVoList.add(copy(comment));
        }
        return commentVoList;
    }

    private CommentVo copy(Comment comment) {
        CommentVo commentVo = new CommentVo();
        BeanUtils.copyProperties(comment, commentVo);
        commentVo.setId(String.valueOf(comment.getId()));
        //作者信息
        String authorId = comment.getAuthorId();
        UserVo userVo = sysUserService.findUserVoById(authorId);
        commentVo.setAuthor(userVo);
        //子评论
        Integer level = comment.getLevel();
        if (level == 1) {
            String id = comment.getId();
            List<CommentVo> commentVoList = findCommentsByParentId(id);
            commentVo.setChildrens(commentVoList);
        }

        //to User 给谁评论
        if (level > 1) {
            String toUid = comment.getToUid();
            UserVo toUserVo = sysUserService.findUserVoById(toUid);
            commentVo.setToUser(toUserVo);
        }
        return commentVo;
    }

    private List<CommentVo> findCommentsByParentId(String id) {
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getParentId, id);
        queryWrapper.eq(Comment::getLevel, 2);
        return copyList(commentsMapper.selectList(queryWrapper));
    }

    @Override
    public Result comment(CommentParam commentParam, String sysUserId) {
        //构建comment
        Comment comment = new Comment();
        comment.setArticleId(commentParam.getArticleId());
        comment.setAuthorId(sysUserId);
        comment.setContent(commentParam.getContent());
        comment.setCreateDate(System.currentTimeMillis());
        String parent = commentParam.getParent();
        if (parent == null || parent == "0") {
            comment.setLevel(1);
        } else {
            comment.setLevel(2);
        }
        comment.setParentId(parent == null ? "0" : parent);
        String toUserId = commentParam.getToUserId();
        comment.setToUid(toUserId == null ? "0" : toUserId);
        commentsMapper.insert(comment);
        // 发起评论后，更新redis文章评论数量
        Article article = articleMapper.selectById(comment.getArticleId());
        threadService.updateArticleCommentCount(articleMapper, article);

        //此处返回CommentVo的目的是让前端收到自己的评论，然后加入到评论显示队列中进行实时显示。
        //这是后端处理评论实时显示的方法之一
        //前端也可以处理
        CommentVo commentVo = copy(comment);
        return Result.success(commentVo);
    }
}
